import cdalib
from argparse import ArgumentParser
import sys


def boot_lk(args, device):
    if args.atf:
        device.send_atf(args.atf)
    device.send_lk(args.file)
    device.boot_lk()


def boot_mtk_da(args, device):
    if args.lk:
        device.send_lk(args.lk)
        device.boot_mtk_da(args.file, True)
    else:
        device.boot_mtk_da(args.file, False)


def read_partition(args, device):
    device.partition_read(args.partition_name, args.output_file)


def write_partition(args, device):
    device.partition_write(args.partition_name, args.input_file)


def boot_pl(args, device):
    device.send_pl(args.file)
    device.boot_pl()


def select_default_port():
    import config
    try:
        return config.AG_DEV_PATH
    except AttributeError:
        print('Define AG_DEV_PATH or specify on command line.')
        sys.exit(1)


def main():
    parser = ArgumentParser()
    parser.add_argument('-w', '--wait', action='store_true',
                        help='Wait for device')
    parser.add_argument('-p', '--port')
    sp = parser.add_subparsers()
    sp_attach_console = sp.add_parser('console')
    sp_attach_console.set_defaults(
        func=lambda args, device: device.attach_console())
    sp_cmd_reboot = sp.add_parser('reboot')
    sp_cmd_reboot.set_defaults(func=lambda args, device: device.reboot())
    sp_cmd_efuse = sp.add_parser(
        'efuse', help='Dump state of various interesting EFUSE bits')
    sp_cmd_efuse.set_defaults(
        func=lambda args, device: device.efuse(False))
    sp_cmd_bootinfo = sp.add_parser(
        'bootinfo', help='Dump bootinfo passed from preloader')
    sp_cmd_bootinfo.set_defaults(
        func=lambda args, device: device.dump_bootinfo()
    )
    sp_cmd_logs = sp.add_parser('logs', help='Dump various logs')
    sp_cmd_logs.set_defaults(func=lambda args, device: device.get_logs())
    sp_cmd_boot_lk = sp.add_parser('boot_lk')
    sp_cmd_boot_lk.add_argument('file')
    sp_cmd_boot_lk.add_argument(
        '--atf', type=str, help='Load ATF (may be required for fully functional LK)')
    sp_cmd_boot_lk.set_defaults(func=boot_lk)

    # dangerous inusable crap
    # sp_cmd_boot_pl = sp.add_parser('boot_pl')
    # sp_cmd_boot_pl.add_argument('file')
    # sp_cmd_boot_pl.set_defaults(func=boot_pl)
    sp_cmd_mmc = sp.add_parser('mmc')
    sp_mmc = sp_cmd_mmc.add_subparsers()
    sp_mmc_cmd_init = sp_mmc.add_parser('init')
    sp_mmc_cmd_init.add_argument('controller', type=int)
    sp_mmc_cmd_init.set_defaults(
        func=lambda args, device: device.mmc_init(args.controller))
    sp_cmd_secpol = sp.add_parser('secpol')
    sp_secpol = sp_cmd_secpol.add_subparsers()
    sp_secpol_cmd_dump = sp_secpol.add_parser('dump')
    sp_secpol_cmd_dump.set_defaults(
        func=lambda args, device: device.secpol_dump())
    sp_secpol_cmd_lock = sp_secpol.add_parser('lock')
    sp_secpol_cmd_lock.set_defaults(
        func=lambda args, device: device.secpol_lock())
    sp_secpol_cmd_unlock = sp_secpol.add_parser('unlock')
    sp_secpol_cmd_unlock.set_defaults(
        func=lambda args, device: device.secpol_unlock())
    sp_cmd_partition = sp.add_parser('partition')
    sp_partition = sp_cmd_partition.add_subparsers()
    sp_partition_cmd_read = sp_partition.add_parser('read')
    sp_partition_cmd_read.add_argument('partition_name')
    sp_partition_cmd_read.add_argument('output_file')
    sp_partition_cmd_read.set_defaults(func=read_partition)
    sp_partition_cmd_write = sp_partition.add_parser('write')
    sp_partition_cmd_write.add_argument('partition_name')
    sp_partition_cmd_write.add_argument('input_file')
    sp_partition_cmd_write.set_defaults(func=write_partition)
    sp_enter_bootrom = sp.add_parser('enter_bootrom')
    sp_enter_bootrom.set_defaults(
        func=lambda args, device: device.enter_bootrom())
    # this is dangerous
    #sp_run_test = sp.add_parser('run_test')
    #sp_run_test.add_argument('test_id', type=int)
    # sp_run_test.set_defaults(
    #    func=lambda args, device: device.run_test(args.test_id))
    args = parser.parse_args()

    if args.port:
        port = args.port
    else:
        port = select_default_port()

    device = cdalib.Device(port, args.wait)

    if hasattr(args, 'func'):
        args.func(args, device)


if __name__ == '__main__':
    main()
